package ru.amse.tsyganov.jumleditor.editor;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;

import ru.amse.tsyganov.jumleditor.commands.Command;
import ru.amse.tsyganov.jumleditor.commands.CommandFactory;
import ru.amse.tsyganov.jumleditor.commands.ViewsManager;
import ru.amse.tsyganov.jumleditor.model.ActivityGraph;
import ru.amse.tsyganov.jumleditor.model.State;
import ru.amse.tsyganov.jumleditor.view.ActivityGraphView;
import ru.amse.tsyganov.jumleditor.view.StateView;

public class DragFiguresMode extends EditorMode {

	public static final DragFiguresMode instance = new DragFiguresMode();
	
	private Rectangle trackingRectangle;
	private StateView<? extends State> selectedView;
	private ViewsManager viewsManager;
	private ActivityGraphView<ActivityGraph> activityGraphView;
	private Canvas canvas;
	
	private int dX;
	private int dY;
	
	private DragFiguresMode() {
	}
	
	public void init(
			ViewsManager viewsManager,
			ActivityGraphView<ActivityGraph> actionGraphView,
			Canvas canvas) {
		
		this.viewsManager = viewsManager;
		this.activityGraphView = actionGraphView;
		this.canvas = canvas;
	}
	
	@Override
	public Cursor getCursor() {
		return new Cursor(null, SWT.CURSOR_ARROW);
	}

	@Override
	public void mouseDoubleClick(MouseEvent e) {
		checkState();
	}

	@Override
	public void mouseDown(MouseEvent e) {
		checkState();
		
		if (e.button != 1) {
			return;
		}
		selectedView = EditorUtil.getControl(
				activityGraphView, e.x, e.y);
		
		if (selectedView == null) {
			return;
		}
		trackingRectangle = selectedView.getRectangle();
		dX = e.x - trackingRectangle.x;
		dY = e.y - trackingRectangle.y;
	}

	@Override
	public void mouseUp(MouseEvent e) {
		checkState();
		
		if (e.button != 1) {
			return;
		}
		if (trackingRectangle != null) {
			assert selectedView != null;
			
			Command c = CommandFactory.createMoveCommand(selectedView, 
					trackingRectangle.x, trackingRectangle.y);
			
			assert viewsManager != null;
			
			viewsManager.executeCommand(c);
			
			trackingRectangle = null;
			selectedView = null;
		}
		canvas.redraw();
	}
	
	@Override
	public void mouseMove(MouseEvent e) {
		if (trackingRectangle != null) {
			redrawRectangleArea();				
			trackingRectangle.x = e.x - dX;
			trackingRectangle.y = e.y - dY;
			redrawRectangleArea();
		} else {
			if (EditorUtil.getControl(activityGraphView, e.x, e.y) != null) {
				canvas.setCursor(new Cursor(null, SWT.CURSOR_SIZEALL));
			} else {
				canvas.setCursor(getCursor());
			}
		}
	}

	@Override
	public void paintControl(PaintEvent e) {
		checkState();
		
		GC gc = e.gc;
		if (trackingRectangle != null) {
			Color grayColor = new Color(null, new RGB(40, 40, 40));
			gc.setForeground(grayColor);
			gc.drawRectangle(trackingRectangle);
		}
	}
	
	private void checkState() {
		if (viewsManager == null ||
				activityGraphView == null ||
				canvas == null) {
			
			throw new IllegalStateException();
		}
	}
	
	private void redrawRectangleArea() {
		canvas.redraw(trackingRectangle.x - 1,
				trackingRectangle.y - 1,
				trackingRectangle.width + 2,
				trackingRectangle.height + 2, false);
	}
}
